VIRQs and IPIs on VCPU#0 are automatically re-bound on save/restore.
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Thu, 29 Sep 2005 12:05:43 +0000 (13:05 +0100)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Thu, 29 Sep 2005 12:05:43 +0000 (13:05 +0100)
Signed-off-by: Keir Fraser <keir@xensource.com>
linux-2.6-xen-sparse/arch/xen/i386/kernel/smp.c
linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c
linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c
linux-2.6-xen-sparse/arch/xen/kernel/reboot.c
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/genapic_xen.c
linux-2.6-xen-sparse/include/asm-xen/asm-i386/mach-xen/irq_vectors.h
linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/irq_vectors.h
linux-2.6-xen-sparse/include/asm-xen/evtchn.h

index 56729ce885314331a92317d73f6f080e0e1fe9d2..5e5ccc8d19b1f0c7a9ea6e337e67abf7ebb42adc 100644 (file)
@@ -131,21 +131,9 @@ DECLARE_PER_CPU(int, ipi_to_evtchn[NR_IPIS]);
 
 static inline void __send_IPI_one(unsigned int cpu, int vector)
 {
-       unsigned int evtchn;
-
-       evtchn = per_cpu(ipi_to_evtchn, cpu)[vector];
-       // printk("send_IPI_mask_bitmask cpu %d vector %d evtchn %d\n", cpu, vector, evtchn);
-       if (evtchn) {
-#if 0
-               shared_info_t *s = HYPERVISOR_shared_info;
-               while (synch_test_bit(evtchn, &s->evtchn_pending[0]) ||
-                      synch_test_bit(evtchn, &s->evtchn_mask[0]))
-                       ;
-#endif
-               notify_via_evtchn(evtchn);
-       } else
-               printk("send_IPI to unbound port %d/%d",
-                      cpu, vector);
+       int evtchn = per_cpu(ipi_to_evtchn, cpu)[vector];
+       BUG_ON(evtchn < 0);
+       notify_via_evtchn(evtchn);
 }
 
 void __send_IPI_shortcut(unsigned int shortcut, int vector)
index 793977fbd657c06d46371e3cbef0931d82c719d9..4642ddd1ad22fef38ae4498b291d196e7841afa6 100644 (file)
@@ -836,13 +836,6 @@ void start_hz_timer(void)
        cpu_clear(smp_processor_id(), nohz_cpu_mask);
 }
 
-void time_suspend(void)
-{
-       /* nothing */
-       teardown_irq(per_cpu(timer_irq, 0), &irq_timer);
-       unbind_virq_from_irq(VIRQ_TIMER);
-}
-
 /* No locking required. We are only CPU running, and interrupts are off. */
 void time_resume(void)
 {
@@ -854,9 +847,6 @@ void time_resume(void)
        per_cpu(processed_system_time, 0) = processed_system_time;
 
        update_wallclock();
-
-       per_cpu(timer_irq, 0) = bind_virq_to_irq(VIRQ_TIMER);
-       (void)setup_irq(per_cpu(timer_irq, 0), &irq_timer);
 }
 
 #ifdef CONFIG_SMP
index 02631a176b10362394f870e7f0222b24d0c1cd63..1f94775476b3f3bad7403e047c73e32dbd65fc3c 100644 (file)
@@ -78,22 +78,28 @@ static u32 cpu_evtchn_mask[NR_CPUS][NR_EVENT_CHANNELS/32];
         cpu_evtchn_mask[cpu][idx] &            \
         ~(sh)->evtchn_mask[idx])
 
-void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu)
+static void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu)
 {
        clear_bit(chn, (unsigned long *)cpu_evtchn_mask[cpu_evtchn[chn]]);
        set_bit(chn, (unsigned long *)cpu_evtchn_mask[cpu]);
        cpu_evtchn[chn] = cpu;
 }
 
+static void init_evtchn_cpu_bindings(void)
+{
+       /* By default all event channels notify CPU#0. */
+       memset(cpu_evtchn, 0, sizeof(cpu_evtchn));
+       memset(cpu_evtchn_mask[0], ~0, sizeof(cpu_evtchn_mask[0]));
+}
+
 #else
 
 #define active_evtchns(cpu,sh,idx)             \
        ((sh)->evtchn_pending[idx] &            \
         ~(sh)->evtchn_mask[idx])
+#define bind_evtchn_to_cpu(chn,cpu)    ((void)0)
+#define init_evtchn_cpu_bindings()     ((void)0)
 
-void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu)
-{
-}
 #endif
 
 /* Upcall to generic IRQ layer. */
@@ -244,7 +250,7 @@ int bind_ipi_to_irq(int ipi)
 
        spin_lock(&irq_mapping_update_lock);
 
-       if ((evtchn = per_cpu(ipi_to_evtchn, cpu)[ipi]) == 0) {
+       if ((evtchn = per_cpu(ipi_to_evtchn, cpu)[ipi]) == -1) {
                op.cmd = EVTCHNOP_bind_ipi;
                BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
                evtchn = op.u.bind_ipi.port;
@@ -287,7 +293,7 @@ void unbind_ipi_from_irq(int ipi)
                bind_evtchn_to_cpu(evtchn, 0);
                evtchn_to_irq[evtchn] = -1;
                irq_to_evtchn[irq]    = -1;
-               per_cpu(ipi_to_evtchn, cpu)[ipi] = 0;
+               per_cpu(ipi_to_evtchn, cpu)[ipi] = -1;
        }
 
        spin_unlock(&irq_mapping_update_lock);
@@ -608,41 +614,32 @@ void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i)
        synch_set_bit(evtchn, &s->evtchn_pending[0]);
 }
 
-void irq_suspend(void)
-{
-       int pirq, virq, irq, evtchn;
-       int cpu = smp_processor_id(); /* XXX */
-
-       /* Unbind VIRQs from event channels. */
-       for (virq = 0; virq < NR_VIRQS; virq++) {
-               if ((irq = per_cpu(virq_to_irq, cpu)[virq]) == -1)
-                       continue;
-               evtchn = irq_to_evtchn[irq];
-
-               /* Mark the event channel as unused in our table. */
-               evtchn_to_irq[evtchn] = -1;
-               irq_to_evtchn[irq]    = -1;
-       }
-
-       /* Check that no PIRQs are still bound. */
-       for (pirq = 0; pirq < NR_PIRQS; pirq++)
-               if ((evtchn = irq_to_evtchn[pirq_to_irq(pirq)]) != -1)
-                       panic("Suspend attempted while PIRQ %d bound "
-                             "to evtchn %d.\n", pirq, evtchn);
-}
-
 void irq_resume(void)
 {
        evtchn_op_t op;
-       int         virq, irq, evtchn;
-       int cpu = smp_processor_id(); /* XXX */
+       int         cpu, pirq, virq, ipi, irq, evtchn;
+
+       init_evtchn_cpu_bindings();
 
        /* New event-channel space is not 'live' yet. */
        for (evtchn = 0; evtchn < NR_EVENT_CHANNELS; evtchn++)
                mask_evtchn(evtchn);
 
+       /* Check that no PIRQs are still bound. */
+       for (pirq = 0; pirq < NR_PIRQS; pirq++)
+               BUG_ON(irq_to_evtchn[pirq_to_irq(pirq)] != -1);
+
+       /* Secondary CPUs must have no VIRQ or IPI bindings. */
+       for (cpu = 1; cpu < NR_CPUS; cpu++) {
+               for (virq = 0; virq < NR_VIRQS; virq++)
+                       BUG_ON(per_cpu(virq_to_irq, cpu)[virq] != -1);
+               for (ipi = 0; ipi < NR_IPIS; ipi++)
+                       BUG_ON(per_cpu(ipi_to_evtchn, cpu)[ipi] != -1);
+       }
+
+       /* Primary CPU: rebind VIRQs automatically. */
        for (virq = 0; virq < NR_VIRQS; virq++) {
-               if ((irq = per_cpu(virq_to_irq, cpu)[virq]) == -1)
+               if ((irq = per_cpu(virq_to_irq, 0)[virq]) == -1)
                        continue;
 
                /* Get a new binding from Xen. */
@@ -652,7 +649,27 @@ void irq_resume(void)
                evtchn = op.u.bind_virq.port;
         
                /* Record the new mapping. */
-               bind_evtchn_to_cpu(evtchn, 0);
+               evtchn_to_irq[evtchn] = irq;
+               irq_to_evtchn[irq]    = evtchn;
+
+               /* Ready for use. */
+               unmask_evtchn(evtchn);
+       }
+
+       /* Primary CPU: rebind IPIs automatically. */
+       for (ipi = 0; ipi < NR_IPIS; ipi++) {
+               if ((evtchn = per_cpu(ipi_to_evtchn, 0)[ipi]) == -1)
+                       continue;
+
+               irq = evtchn_to_irq[evtchn];
+               evtchn_to_irq[evtchn] = -1;
+
+               /* Get a new binding from Xen. */
+               op.cmd = EVTCHNOP_bind_ipi;
+               BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
+               evtchn = op.u.bind_ipi.port;
+        
+               /* Record the new mapping. */
                evtchn_to_irq[evtchn] = irq;
                irq_to_evtchn[irq]    = evtchn;
 
@@ -670,15 +687,15 @@ void __init init_IRQ(void)
 
        spin_lock_init(&irq_mapping_update_lock);
 
-#ifdef CONFIG_SMP
-       /* By default all event channels notify CPU#0. */
-       memset(cpu_evtchn_mask[0], ~0, sizeof(cpu_evtchn_mask[0]));
-#endif
+       init_evtchn_cpu_bindings();
 
        for (cpu = 0; cpu < NR_CPUS; cpu++) {
                /* No VIRQ -> IRQ mappings. */
                for (i = 0; i < NR_VIRQS; i++)
                        per_cpu(virq_to_irq, cpu)[i] = -1;
+               /* No VIRQ -> IRQ mappings. */
+               for (i = 0; i < NR_IPIS; i++)
+                       per_cpu(ipi_to_evtchn, cpu)[i] = -1;
        }
 
        /* No event-channel -> IRQ mappings. */
index b3d6874b0ad0caf1d48b52e563b240ff6ec6c7b6..03fff886aa8b0376061f4986f61ade2157ab9065 100644 (file)
@@ -74,16 +74,12 @@ static int __do_suspend(void *ignore)
        extern int gnttab_suspend(void);
        extern int gnttab_resume(void);
 
-       extern void time_suspend(void);
        extern void time_resume(void);
        extern unsigned long max_pfn;
        extern unsigned long *pfn_to_mfn_frame_list_list;
        extern unsigned long *pfn_to_mfn_frame_list[];
 
 #ifdef CONFIG_SMP
-       extern void smp_suspend(void);
-       extern void smp_resume(void);
-
        static vcpu_guest_context_t suspended_cpu_records[NR_CPUS];
        cpumask_t prev_online_cpus, prev_present_cpus;
 
@@ -156,18 +152,10 @@ static int __do_suspend(void *ignore)
        kmem_cache_shrink(pgd_cache);
 #endif
 
-       time_suspend();
-
-#ifdef CONFIG_SMP
-       smp_suspend();
-#endif
-
        xenbus_suspend();
 
        xencons_suspend();
 
-       irq_suspend();
-
        gnttab_suspend();
 
        HYPERVISOR_shared_info = (shared_info_t *)empty_zero_page;
@@ -212,10 +200,6 @@ static int __do_suspend(void *ignore)
 
        xenbus_resume();
 
-#ifdef CONFIG_SMP
-       smp_resume();
-#endif
-
        time_resume();
 
        usbif_resume();
index 139ce282d8a51b5632867c6dbb982aad139ef291..807f0fd9b4b0fbd9c78f3df1d6e08faebff5dbdd 100644 (file)
@@ -31,14 +31,9 @@ DECLARE_PER_CPU(int, ipi_to_evtchn[NR_IPIS]);
 
 static inline void __send_IPI_one(unsigned int cpu, int vector)
 {
-       unsigned int evtchn;
-       Dprintk("%s\n", __FUNCTION__);
-
-       evtchn = per_cpu(ipi_to_evtchn, cpu)[vector];
-       if (evtchn)
-               notify_via_evtchn(evtchn);
-       else
-               printk("send_IPI to unbound port %d/%d", cpu, vector);
+       int evtchn = per_cpu(ipi_to_evtchn, cpu)[vector];
+       BUG_ON(evtchn < 0);
+       notify_via_evtchn(evtchn);
 }
 
 void xen_send_IPI_shortcut(unsigned int shortcut, int vector, unsigned int dest)
index f4cde5f102229a03e3abfaa0e9300be13e19c68c..49e5ac07f075ce4a2b31f657b68643eb7f2d8b5b 100644 (file)
  * the usable vector space is 0x20-0xff (224 vectors)
  */
 
-#define NR_IPIS 8
-
-#define RESCHEDULE_VECTOR      1
-#define INVALIDATE_TLB_VECTOR  2
-#define CALL_FUNCTION_VECTOR   3
+#define RESCHEDULE_VECTOR      0
+#define CALL_FUNCTION_VECTOR   1
+#define NR_IPIS                        2
 
 /*
  * The maximum number of vectors supported by i386 processors
index 690560c8236074ad490b7e8736c91ae2c6859bc8..c7d85b1967543f1f2d7ed68a2b2cd4c7149424c1 100644 (file)
  * the usable vector space is 0x20-0xff (224 vectors)
  */
 
-#define NR_IPIS 8
-
-#define RESCHEDULE_VECTOR      1
-#define INVALIDATE_TLB_VECTOR  2
-#define CALL_FUNCTION_VECTOR   3
+#define RESCHEDULE_VECTOR      0
+#define CALL_FUNCTION_VECTOR   1
+#define NR_IPIS                        2
 
 /*
  * The maximum number of vectors supported by i386 processors
index e60155206be68f68f71371e4bc1436c0110fe5ed..d364b0a4b516e601e3537d9b784abbdbb837a023 100644 (file)
@@ -68,7 +68,6 @@ extern int  bind_evtchn_to_irqhandler(
        void *dev_id);
 extern void unbind_evtchn_from_irqhandler(unsigned int evtchn, void *dev_id);
 
-extern void irq_suspend(void);
 extern void irq_resume(void);
 
 /* Entry point for notifications into Linux subsystems. */